<?php
/**
 * @author       Sixe Team
 * @email        info@eee-eee.com
 * @url          http://www.eee-eee.com
 * @copyright    Copyright (C) 2010 - 2019 Sixe Information Technology Limited. All rights reserved.
 * @license      GNU General Public License version 2 or later; see LICENSE.txt
 * @date         2019/10/01 10:00
 */

defined('JPATH_PLATFORM') or die;

use Joomla\Utilities\ArrayHelper;


JFormHelper::loadFieldClass('list');


/**
 * Field to load a dropdown list of available user groups
 *
 * @since  3.2
 */
class JFormFieldCategoryFlow extends JFormFieldList
{
	/**
	 * The form field type.
	 *
	 * @var        string
	 * @since   3.2
	 */
	public $type = 'CategoryFlow';

	/**
	 * Method to attach a JForm object to the field.
	 *
	 * @param   \SimpleXMLElement $element The SimpleXMLElement object representing the `<field>` tag for the form field object.
	 * @param   mixed $value The form field value to validate.
	 * @param   string $group The field name group control value. This acts as an array container for the field.
	 *                                       For example if the field has name="foo" and the group value is set to "bar" then the
	 *                                       full field name would end up being "bar[foo]".
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   1.7.0
	 */
	public function setup(SimpleXMLElement $element, $value, $group = null)
	{
		return parent::setup($element, $value, $group);
	}


	protected function getcatids()
	{
		$options = array();
		$published = $this->element['published'] ? explode(',', (string)$this->element['published']) : array(0, 1);
		$name = (string)$this->element['name'];

		// Let's get the id for the current item, either category or content item.
		$jinput = JFactory::getApplication()->input;

		// Load the category options for a given extension.

		// For categories the old category is the category id or 0 for new category.
		if ($this->element['parent'] || $jinput->get('option') == 'com_categories') {
			$oldCat = $jinput->get('id', 0);
			$oldParent = $this->form->getValue($name, 0);
			$extension = $this->element['extension'] ? (string)$this->element['extension'] : (string)$jinput->get('extension', 'com_content');
		} else // For items the old category is the category they are in when opened or 0 if new.
		{
			$oldCat = $this->form->getValue($name, 0);
			$extension = $this->element['extension'] ? (string)$this->element['extension'] : (string)$jinput->get('option', 'com_content');
		}

		// Account for case that a submitted form has a multi-value category id field (e.g. a filtering form), just use the first category
		$oldCat = is_array($oldCat)
			? (int)reset($oldCat)
			: (int)$oldCat;

		$db = JFactory::getDbo();
		$user = JFactory::getUser();

		$query = $db->getQuery(true)
			->select('a.id AS value, a.title AS text, a.level, a.published, a.lft, a.language')
			->from('#__categories AS a');

		// Filter by the extension type
		if ($this->element['parent'] == true || $jinput->get('option') == 'com_categories') {
			$query->where('(a.extension = ' . $db->quote($extension) . ' OR a.parent_id = 0)');
		} else {
			$query->where('(a.extension = ' . $db->quote($extension) . ')');
		}

		// Filter language
		if (!empty($this->element['language'])) {
			if (strpos($this->element['language'], ',') !== false) {
				$language = implode(',', $db->quote(explode(',', $this->element['language'])));
			} else {
				$language = $db->quote($this->element['language']);
			}

			$query->where($db->quoteName('a.language') . ' IN (' . $language . ')');
		}

		// Filter on the published state
		$query->where('a.published IN (' . implode(',', ArrayHelper::toInteger($published)) . ')');

		// Filter categories on User Access Level
		// Filter by access level on categories.
		if (!$user->authorise('core.admin')) {
			$groups = implode(',', $user->getAuthorisedViewLevels());
			$query->where('a.access IN (' . $groups . ')');
		}

		$query->order('a.lft ASC');

		// If parent isn't explicitly stated but we are in com_categories assume we want parents
		if ($oldCat != 0 && ($this->element['parent'] == true || $jinput->get('option') == 'com_categories')) {
			// Prevent parenting to children of this item.
			// To rearrange parents and children move the children up, not the parents down.
			$query->join('LEFT', $db->quoteName('#__categories') . ' AS p ON p.id = ' . (int)$oldCat)
				->where('NOT(a.lft >= p.lft AND a.rgt <= p.rgt)');

			$rowQuery = $db->getQuery(true);
			$rowQuery->select('a.id AS value, a.title AS text, a.level, a.parent_id')
				->from('#__categories AS a')
				->where('a.id = ' . (int)$oldCat);
			$db->setQuery($rowQuery);
			$row = $db->loadObject();
		}

		// Get the options.
		$db->setQuery($query);

		try {
			$options = $db->loadObjectList();
		} catch (RuntimeException $e) {
			JError::raiseWarning(500, $e->getMessage());
		}

		return array_merge(parent::getOptions(), $options);
	}


	/**
	 * Method to get the options to populate list
	 *
	 * @return  array  The field option objects.
	 *
	 * @since   3.2
	 */
	protected function getOptions()
	{
		$app = JFactory::getApplication();
		$option = $app->input->getCmd('option', 'com_content');
		$options = $this->getcatids();
		$user = JFactory::getUser();

		// Let's get the id for the current item, either category or content item.
		$db = JFactory::getDbo();
		$groups = implode(',', $user->groups);

		$query = $db->getQuery(true)
			->select("DISTINCT a.category_id")
			->from('#__workflow_categories AS a');
		if ($option == 'com_sixeworkflow' && $app->issite()) {
			$query->join('LEFT', '#__workflow_users AS u ON u.workflow_id=a.workflow_id')
				->where('(u.type=1 AND u.user_id IN (' . $groups . ')) OR (u.type=2 AND u.user_id=' . $user->id . ')');
		}

		// Get the options.
		$db->setQuery($query);
		try {
			$catids = $db->loadColumn();
			//print_r($catids);

		} catch (RuntimeException $e) {
			JError::raiseWarning(500, $e->getMessage());
		}
		if ($option == 'com_content') {
			foreach ($options as $key => $co) {
				if (in_array($co->value, $catids)) {
					//unset($options[$key]);
				}
			}
		} elseif ($option == 'com_sixeworkflow') {
			foreach ($options as $key => $co) {
				if (!in_array($co->value, $catids) && $co->value != '') {
					unset($options[$key]);
				}
			}
		}

		return $options;
	}


	protected function getInput()
	{
		$options = $this->getOptions();

		if (count($options)) {
			return parent::getInput();
		} else {
			return '<input type="text" readonly="true" placeholder="' . JText::_('JGLOBAL_TYPE_OR_SELECT_CATEGORY') . '" />';
		}
	}

}
